package cn.com.yusys.yusp.message.service.message;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import cn.com.yusys.yusp.admin.service.UserProviderService;
import cn.com.yusys.yusp.commons.util.CommonUtil;
import cn.com.yusys.yusp.commons.util.DateUtil;
import cn.com.yusys.yusp.message.domain.MessageContent;
import cn.com.yusys.yusp.message.domain.MessagePool;
import cn.com.yusys.yusp.message.domain.MessagePoolHis;
import cn.com.yusys.yusp.message.repository.mapper.MessageContentMapper;
import cn.com.yusys.yusp.message.repository.mapper.MessagePoolHisMapper;
import cn.com.yusys.yusp.message.repository.mapper.MessagePoolMapper;
import cn.com.yusys.yusp.message.service.message.channel.impl.EmailSendService;
import cn.com.yusys.yusp.message.service.message.channel.impl.MobileSendService;
import cn.com.yusys.yusp.message.service.message.channel.impl.SystemSendService;
import cn.com.yusys.yusp.message.service.message.filter.EmailAttachmentCustomInterface;
import cn.com.yusys.yusp.message.service.message.util.ParamUtil;

@Service
public class MessageSendThread {
	private Logger logger = LoggerFactory.getLogger(MessageSendThread.class);

	@Autowired
	private MessagePoolMapper messagePoolMapper;
	
	@Autowired
	private MessagePoolHisMapper messagePoolHisMapper;

	@Autowired
	private MessageContentMapper messageContentMapper;
	
	@Autowired
	private UserProviderService userService;
	
	@Autowired
	private EmailSendService emailUtilService;
	
	@Autowired
	private MobileSendService mobileUtilService;
	
	@Autowired
	private SystemSendService systemUtilService;
	
	@Autowired(required=false)
	private List<EmailAttachmentCustomInterface> attachmentCustomInterface;
	
	@Async("taskExecutor")
	public void sendMessageThread(MessagePool messagePool) {

		String key = messagePool.getPkNo();

		try {
			MessagePool acptMessageSend = messagePoolMapper.selectByPrimaryKey(key);
			
			// 处于待发送状态才会发送
			if (null!=acptMessageSend&&MessageConst.SENDING.equals(acptMessageSend.getState())) {
				
				// 获取发送内容
				String channel = acptMessageSend.getChannelType();
				MessageContent param = new MessageContent();
				param.setEventNo(acptMessageSend.getEventNo());
				param.setChannelType(channel);
				List<MessageContent> list = messageContentMapper.select(param);

				if (null != list && !list.isEmpty()) {
					MessageContent messageContentT = list.get(0);
					
					// 获取用户基本信息
					//List<Map<String,Object>> userInfos = orgMapper.selectUserInfo(acptMessageSend.getUserNo());
					Map<String, Object> userInfo = userService.queryUserInfoByUserId(acptMessageSend.getUserNo());
					if(CommonUtil.isNullOrEmpty(userInfo)/*userInfos.isEmpty()*/){
						logger.error("[sending failed] {}, unable to get basic user information{}", acptMessageSend.getPkNo(), acptMessageSend.getUserNo());
						// 移除消息队列，记录消息发送历史
						transferData( 1 ,acptMessageSend);
					}else{
						//Map<String,Object> userInfo = userInfos.get(0);
						// 获取消息内容
						String messageContent = messageContentT.getContent();
						messageContent = ParamUtil.replaceParam(messageContent, userInfo);
						// 发送结果
						int result = 0;
						// 发送邮件
						if (MessageConst.EMAIL.equals(channel)) {
							
							if(null==userInfo.get("email")||((String)userInfo.get("email")).trim().equals("")){
								result = 1;
								logger.error("[Invalid parameter]"+acptMessageSend.getPkNo()+",User{"+acptMessageSend.getUserNo()+"} email is empty");			
							}else{
								result = emailUtilService.sendHtmlEmailWithAttachment((String)userInfo.get("email"),messageContentT.getEmailTitle(),messageContent,getAttachment( acptMessageSend.getMessageType(),acptMessageSend.getUserNo()),messageContentT.getSendNum());
							}
							if (0 == result) {
								logger.debug("[Success][Email] send to " + acptMessageSend.getUserNo());
							} else {
								logger.error("[Failed][Email] send to" + acptMessageSend.getUserNo());
							}
	
						} else if (MessageConst.MOBILE.equals(channel)) {// 发送短信[待完成]
							if(null==userInfo.get("mobile")||((String)userInfo.get("mobile")).trim().equals("")){
								result = 1;
								logger.error("[Invalid parameter]"+acptMessageSend.getPkNo()+",User{"+acptMessageSend.getUserNo()+"}Mobile phone number is empty");			
							}else{
								result = mobileUtilService.sendMessage(((String)userInfo.get("mobile")).trim(), messageContent, messageContentT.getSendNum());
							}
							if (0 == result) {
								logger.debug("[Success][SMS] send to" + acptMessageSend.getUserNo());
							} else {
								logger.error("[Failed][SMS] send to" + acptMessageSend.getUserNo());
							}
						} else if (MessageConst.SYSTEM.equals(channel)) {// 发送系统消息
							if(null==userInfo.get("userNo")||((String)userInfo.get("userNo")).trim().equals("")){
								result = 1;
								logger.error("[Invalid parameter]"+acptMessageSend.getPkNo()+",User{"+acptMessageSend.getUserNo()+"}ID is empty");			
							}else{
								result = systemUtilService.sendMessage(((String)userInfo.get("userNo")).trim(),messageContentT.getEmailTitle(), messageContent, messageContentT.getSendNum());							
							}
						
							if (0 == result) {
								logger.debug("[Success][System message] send to" + acptMessageSend.getUserNo());
							} else {
								logger.error("[Failed][System message] send to" + acptMessageSend.getUserNo());
							}
								
						}
	
						// 移除消息队列，记录消息发送历史
						transferData( result ,acptMessageSend);
					}
				}else{							
					logger.error("[Sending failed]"+acptMessageSend.getPkNo()+",the corresponding message content is not obtained and cannot be sent. The serial number is:"+acptMessageSend.getEventNo()+",the channel type is:"+channel);
					// 移除消息队列，记录消息发送历史
					transferData( 1 ,acptMessageSend);
				}
			}else{
				logger.warn("Message details is not obtained, sent:"+key);
			}

		} catch (Exception e) {
			e.printStackTrace();
			logger.error("Exception in message sending process:\n"+e);
		} 
	}
	
	private void transferData(int result ,MessagePool messagePool){
		MessagePoolHis messagePoolHis = new MessagePoolHis();
		messagePoolHis.setChannelType(messagePool.getChannelType());
		messagePoolHis.setCreateTime(messagePool.getCreateTime());
		messagePoolHis.setEventNo(messagePool.getEventNo());
		messagePoolHis.setMessageLevel(messagePool.getMessageLevel());
		messagePoolHis.setPkHash(messagePool.getPkHash());
		messagePoolHis.setPkNo(messagePool.getPkNo());
		messagePoolHis.setTimeStart(messagePool.getTimeStart());
		messagePoolHis.setUserNo(messagePool.getUserNo());
		messagePoolHis.setMessageType(messagePool.getMessageType());
		if(result == 0){
			messagePoolHis.setState(MessageConst.SEND_END);
		}else{
			messagePoolHis.setState(MessageConst.SEND_EXCEPTION);
		}
		messagePoolHis.setSendTime(DateUtil.formatDate(DateUtil.PATTERN_DATETIME_COMPACT));			
		messagePoolMapper.deleteByPrimaryKey(messagePool.getPkNo());
		messagePoolHisMapper.insertSelective(messagePoolHis);
	}
	
	private Map<String,byte[]> getAttachment(String messageType,String userNo) {
		Map<String,byte[]> attachments= new HashMap<String,byte[]>();
		// 自定义人邮件附件
		if (null != attachmentCustomInterface && !attachmentCustomInterface.isEmpty()) {
			for (EmailAttachmentCustomInterface filter : attachmentCustomInterface) {
				if (filter.isFixed(messageType)) {
					attachments =  filter. getAttachments( messageType, userNo);
					break;
				}
			}
		}
		return attachments;
	}
}
